---
title: Splitter
description: Using the splitter machine in your project.
package: "@zag-js/splitter"
---

A splitter allow create dynamic layouts split into vertically or horizontally
arranged panes. Panes are separated by the splitter bars that allow dragging to
resize or expand/collapse them.

<Resources pkg="@zag-js/splitter" />

<Showcase id="Splitter" />

**Features**

- Built with flexbox for flexible layout and SSR
- Support both dynamic horizontal and vertical panels
- Support multiple panels and splitters
- Support for collapsible panels
- Support for panel constraints like min and max sizes
- Programmatic control of panel sizes
- Implements the
  [Window Splitter pattern](https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/)
  for accessibility and keyboard controls

## Installation

To use the splitter machine in your project, run the following command in your
command line:

<CodeSnippet id="splitter/installation.mdx" />

## Anatomy

To set up the slider correctly, you'll need to understand its anatomy and how we
name its parts.

> Each part includes a `data-part` attribute to help identify them in the DOM.

<Anatomy id="splitter" />

## Usage

First, import the splitter package into your project

```jsx
import * as splitter from "@zag-js/splitter"
```

The splitter package exports two key functions:

- `machine` — The state machine logic for the splitter widget.
- `connect` — The function that translates the machine's state to JSX attributes
  and event handlers.

> You'll also need to provide a unique `id` to the `useMachine` hook. This is
> used to ensure that every part has a unique identifier.

Next, import the required hooks and functions for your framework and use the
splitter machine in your project 🔥

<CodeSnippet id="splitter/usage.mdx" />

### Setting the initial size

To set the initial size of the splitter panels, use the `defaultSize` property.
Ensure the `defaultSize` totals to `100`.

> Note: The splitter only supports setting percentage values.

```jsx {3}
const service = useMachine(splitter.machine, {
  // ...
  defaultSize: [40, 60],
})
```

### Listening for resize events

When the resize trigger is dragged, the `onResize`, `onResizeStart` and
`onResizeEnd` callback is invoked.

```jsx {3-10}
const service = useMachine(splitter.machine, {
  // ...
  onResize(detail) {
    console.log("resize", detail)
  },
  onResizeStart(detail) {
    console.log("change start", detail)
  },
  onResizeEnd(detail) {
    console.log("change end", detail)
  },
})
```

### Changing the orientation

By default, the splitter is assumed to be horizontal. To change the orientation
to vertical, set the `orientation` property in the machine's context to
`vertical`.

```jsx {3}
const service = useMachine(splitter.machine, {
  // ...
  orientation: "vertical",
})
```

## Specifying constraints

Use the `panels` property to specify constraints like `minSize` and `maxSize`
for the splitter panels.

```jsx {3-6}
const service = useMachine(splitter.machine, {
  // ...
  panels: [
    { id: "a", minSize: 100, maxSize: 300 },
    { id: "b", minSize: 100, maxSize: 300 },
  ],
})
```

### Setting the collapsed size

Set the `collapsedSize` and `collapsible` of a panel to specify the collapsed
size of the panel.

> For best results, ensure you also set the `minSize` of the panel

```jsx {4}
const service = useMachine(splitter.machine, {
  // ...
  panels: [
    { id: "a", collapsible: true, collapsedSize: 5, minSize: 10, maxSize: 20 },
    { id: "b", minSize: 50 },
  ],
})
```

This allows the user to drag the splitter to collapse the panel to the
`collapsedSize`.

### Listening for collapse events

When the splitter panel is collapsed, the `onCollapse` callback is invoked.
Alternatively, the `onExpand` callback is invoked when the panel is expanded.

```jsx {3-8}
const service = useMachine(splitter.machine, {
  // ...
  onCollapse(detail) {
    console.log("collapse", detail)
  },
  onExpand(detail) {
    console.log("expand", detail)
  },
})
```

## Styling guide

Earlier, we mentioned that each accordion part has a `data-part` attribute added
to them to select and style them in the DOM.

### Resize trigger

When an splitter item is horizontal or vertical, a `data-state` attribute is set
on the item and content elements.

```css
[data-scope="splitter"][data-part="resize-trigger"] {
  /* styles for the item */
}

[data-scope="splitter"][data-part="resize-trigger"][data-orientation="horizontal"] {
  /* styles for the item is horizontal state */
}

[data-scope="splitter"][data-part="resize-trigger"][data-orientation="vertical"] {
  /* styles for the item is horizontal state */
}

[data-scope="splitter"][data-part="resize-trigger"][data-focus] {
  /* styles for the item is focus state */
}

[data-scope="splitter"][data-part="resize-trigger"]:active {
  /* styles for the item is active state */
}

[data-scope="splitter"][data-part="resize-trigger"][data-disabled] {
  /* styles for the item is disabled state */
}
```

## Methods and Properties

The splitter's `api` exposes the following methods and properties:

### Machine Context

The splitter machine exposes the following context properties:

<ContextTable name="splitter" />

### Machine API

The splitter `api` exposes the following methods:

<ApiTable name="splitter" />

### Data Attributes

<DataAttrTable name="splitter" />
